/*
1.function matrix_calc_taskA,matrix_calc_taskB
2."size" means iteration times
*/
#ifndef _CALC_H_
#define _CALC_H_

#ifdef __cplusplus
extern "C"{	
#endif

typedef struct {
	int* 			rowArray;
	const int* 		rowOffset;
	int 			rowArraySize;
	const int* 		columnIndice;
	const double* 	S;
	const double*	valueNormalMatrix;
	double* 		Id;
}TaskMatrixInfoA;

typedef struct {
	const double * 	valueSpiceMatrix;//N*2
	const int* 		rowOffset; 		//n+1
	const int* 		columnIndice; 	//N

	double* 		A;	//N
	double*		 	S;	//nx1
	double*			R;	//nx1
	double* 		H;	//nx1
	const double* 	D;	//N*2
	double* 		IC;	//nx1
	double* 		IG;	//nx1
	double 		alpha;
	int * 			rowArray; //kx1
	int 			rowArraySize;
	void* 			hdl;  //? what's this?
}TaskMatrixInfoB;

void matrix_calc_taskA(TaskMatrixInfoA** listDataList,int N)
{
	for (int i = 0 ;i < N; ++i)
	{		
		for (unsigned int it = 0; it < listDataList[i]->rowArraySize; ++it	)
		{
			const int node = listDataList[i]->rowArray[it];

			for (int j = listDataList[i]->rowOffset[node];j < listDataList[i]->rowOffset[node + 1];++j)
			{
				listDataList[i]->Id[node] +=listDataList[i]->valueNormalMatrix[j] * listDataList[i]->S[listDataList[i]->columnIndice[j]];
			}
		}
	}
}

//Task B interface
void matrix_calc_taskB(TaskMatrixInfoB** listDataList,int N)
{
 
	for (int i = 0;i<N;i++){
		//(4)(5)
		for(int it = 0;it < listDataList[i]->rowArraySize;++it)
		{
			int row = listDataList[i]->rowArray[it];
	
			for (int p = listDataList[i]->rowOffset[row];p < listDataList[i]->rowOffset[row + 1];++p){
				int col = listDataList[i]->columnIndice[p];
				const int k = p * 2;
				double cond =listDataList[i]->valueSpiceMatrix[k];
				double cap  =listDataList[i]->valueSpiceMatrix[k+1];
	
				listDataList[i]->IG[row] += cond * listDataList[i]->S[col];
				listDataList[i]->IC[row] += cap * listDataList[i]->S[col]	;
			} 
		} 
 		//	(7)(8)
		for (int it = 0; it < listDataList[i]->rowArraySize;++it)
		{
			int row = listDataList[i]->rowArray[it];
			const int k1 = row * 2;
			double current = listDataList[i]->D[k1];
			double charge = listDataList[i]->D[k1+1];
	
			for (int p = listDataList[i]->rowOffset[row];p<listDataList[i]->rowOffset[row + 1];++p){
				int col = listDataList[i]->columnIndice[p];
				const int k = p*2;

				current -= listDataList[i]->valueSpiceMatrix[k] * listDataList[i]->S[col];
				charge -= listDataList[i]->valueSpiceMatrix[k+1]* listDataList[i]->S[col];
			}
			listDataList[i]->R[row] = current;
			listDataList[i]->H[row] = charge;
		}
 		//	(9)
		for (int it = 0;it < listDataList[i]->rowArraySize;++it)
		{
			int row = listDataList[i]->rowArray[it];
		
			for(int p = listDataList[i]->rowOffset[row];p < listDataList[i]->rowOffset[row+1];++p)
			{
				const int k = p*2;
				double cond = listDataList[i]->valueSpiceMatrix[k];
				double cap = listDataList[i]->valueSpiceMatrix[k+1];
				listDataList[i]->A[p] = cond +  cap * listDataList[i]->alpha;
			}
		}
	}
}

#ifdef __cplusplus
}
#endif

#endif